package at.ac.uniklu.rallyemaster.activities;

import java.util.ArrayList;
import java.util.List;

import android.content.Intent;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.LinearLayout;
import android.widget.Toast;
import at.ac.uniklu.rallyemaster.GeoHelper;
import at.ac.uniklu.rallyemaster.R;
import at.ac.uniklu.rallyemaster.RallyeMaster;
import at.ac.uniklu.rallyemaster.ShowTrackMapOverlay;
import at.ac.uniklu.rallyemaster.adapters.DBTrack;
import at.ac.uniklu.rallyemaster.adapters.DBTrackingPoint;
import at.ac.uniklu.rallyemaster.domain.Track;
import at.ac.uniklu.rallyemaster.domain.TrackingPoint;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
import de.android1.overlaymanager.ManagedOverlay;
import de.android1.overlaymanager.ManagedOverlayGestureDetector;
import de.android1.overlaymanager.ManagedOverlayItem;
import de.android1.overlaymanager.OverlayManager;
import de.android1.overlaymanager.ZoomEvent;


public class ShowTrackActivity extends MapActivity{

	private static final int CONTEXT_ADD = Menu.FIRST;

	private static final int NEW_TRACK = Menu.FIRST;
	private static final int OPTIONS_ITEM = Menu.FIRST+1;
	
	private LinearLayout startButtonLayout;
	private DBTrackingPoint dbTrackingPoint;
	private DBTrack dbTrack;
	private ArrayList<TrackingPoint> trackingPoints;
	private Track currentTrack;
	private int selectedTrackID;
	private GeoPoint addGeoPoint;
	
	private MapView mapView;
	private GeoPoint geoPoint;
	private OverlayItem overlayItem;
	
	private boolean firstCall;
	
	private List<Overlay> overlays;
	private ShowTrackMapOverlay showTrackMapOverlay;
	private ShowTrackMapOverlay showTrackMapOverlayInfo;
	private ShowTrackMapOverlay showTrackMapOverlaycurve0;
	private ShowTrackMapOverlay showTrackMapOverlaycurve1;
	private ShowTrackMapOverlay showTrackMapOverlaycurve2;
	private ShowTrackMapOverlay showTrackMapOverlaycurve3;
	private ShowTrackMapOverlay showTrackMapOverlaycurve4;
	private ShowTrackMapOverlay showTrackMapOverlaycurve5;
	private ShowTrackMapOverlay showTrackMapOverlaycurve6;
	
	private ArrayList<TrackingPoint> trackingPointsNone;
	private ArrayList<TrackingPoint> trackingPointsInfo;
	private ArrayList<TrackingPoint> trackingPointsCurve0;
	private ArrayList<TrackingPoint> trackingPointsCurve1;
	private ArrayList<TrackingPoint> trackingPointsCurve2;
	private ArrayList<TrackingPoint> trackingPointsCurve3;
	private ArrayList<TrackingPoint> trackingPointsCurve4;
	private ArrayList<TrackingPoint> trackingPointsCurve5;
	private ArrayList<TrackingPoint> trackingPointsCurve6;
	
	private OverlayManager overlayManager;

	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		
		setContentView(R.layout.map_layout);
		
		mapView = (MapView) findViewById(R.id.mapview);
		mapView.setBuiltInZoomControls(true);
		mapView.setClickable(true);
		mapView.getController().setZoom(15);
		registerForContextMenu(mapView);
		
		firstCall = true;
		
		startButtonLayout = (LinearLayout)findViewById(R.id.startButtonLayout);
		startButtonLayout.setVisibility(LinearLayout.GONE);
		
		selectedTrackID = getIntent().getExtras().getInt("TrackID",0);
		//RallyeMaster.logDebug("Selected Track ID: " + selectedTrackID);
		
		trackingPoints = new ArrayList<TrackingPoint>();
		trackingPointsNone = new ArrayList<TrackingPoint>();
		trackingPointsInfo = new ArrayList<TrackingPoint>();
		trackingPointsCurve0 = new ArrayList<TrackingPoint>();
		trackingPointsCurve1 = new ArrayList<TrackingPoint>();
		trackingPointsCurve2 = new ArrayList<TrackingPoint>();
		trackingPointsCurve3 = new ArrayList<TrackingPoint>();
		trackingPointsCurve4 = new ArrayList<TrackingPoint>();
		trackingPointsCurve5 = new ArrayList<TrackingPoint>();
		trackingPointsCurve6 = new ArrayList<TrackingPoint>();
		
		dbTrackingPoint = new DBTrackingPoint();
		dbTrack = new DBTrack();
		currentTrack = dbTrack.getTrackByID(selectedTrackID);
		setTitle(currentTrack.getName());
		
		// getting tracks from Database
		trackingPoints = dbTrackingPoint.getTrackingPointsFromTrack(selectedTrackID);
		//RallyeMaster.logDebug("TrackingPoints in db: " + trackingPoints.size());
		
		showTrackMapOverlay = new ShowTrackMapOverlay(mapView.getResources().getDrawable(R.drawable.marker_green), this, "none", trackingPointsNone);
		showTrackMapOverlayInfo = new ShowTrackMapOverlay(mapView.getResources().getDrawable(R.drawable.marker_info), this,"info", trackingPointsInfo);
		showTrackMapOverlaycurve0 = new ShowTrackMapOverlay(mapView.getResources().getDrawable(R.drawable.marker_curve), this,"curve0", trackingPointsCurve0);
		showTrackMapOverlaycurve1 = new ShowTrackMapOverlay(mapView.getResources().getDrawable(R.drawable.marker_curve_1), this,"curve1", trackingPointsCurve1);
		showTrackMapOverlaycurve2 = new ShowTrackMapOverlay(mapView.getResources().getDrawable(R.drawable.marker_curve_2), this,"curve2", trackingPointsCurve2);
		showTrackMapOverlaycurve3 = new ShowTrackMapOverlay(mapView.getResources().getDrawable(R.drawable.marker_curve_3), this,"curve3", trackingPointsCurve3);
		showTrackMapOverlaycurve4 = new ShowTrackMapOverlay(mapView.getResources().getDrawable(R.drawable.marker_curve_4), this,"curve4", trackingPointsCurve4);
		showTrackMapOverlaycurve5 = new ShowTrackMapOverlay(mapView.getResources().getDrawable(R.drawable.marker_curve_5), this,"curve5", trackingPointsCurve5);
		showTrackMapOverlaycurve6 = new ShowTrackMapOverlay(mapView.getResources().getDrawable(R.drawable.marker_curve_6), this,"curve6", trackingPointsCurve6);
		
		fillShowTrackMapOverlay(trackingPoints);
		overlayManager = new OverlayManager(getApplication(), mapView);
		overlays = mapView.getOverlays();
		overlays.clear();
		overlays.add(showTrackMapOverlay);
		overlays.add(showTrackMapOverlayInfo);
		overlays.add(showTrackMapOverlaycurve0);
		overlays.add(showTrackMapOverlaycurve1);
		overlays.add(showTrackMapOverlaycurve2);
		overlays.add(showTrackMapOverlaycurve3);
		overlays.add(showTrackMapOverlaycurve4);
		overlays.add(showTrackMapOverlaycurve5);
		overlays.add(showTrackMapOverlaycurve6);
	}


	// fills the Map Overlay with items
	private void fillShowTrackMapOverlay(ArrayList<TrackingPoint> trackingPoints){
		for(int i = 0; i<trackingPoints.size(); i++){
			geoPoint = new GeoPoint((int)(trackingPoints.get(i).getLatitude()*1E6), (int)(trackingPoints.get(i).getLongitude()*1E6));
			overlayItem = new OverlayItem(geoPoint, "trackingPoint", "this is a tracking point");
		
			
			//setting the right overlay with the right marker
			if(trackingPoints.get(i).getCurve()){
				switch(trackingPoints.get(i).getCurveIntension()){
				case(0):
					trackingPointsCurve0.add(trackingPoints.get(i));
					showTrackMapOverlaycurve0.addOverlayItem(overlayItem);
					break;
				case(1):
					trackingPointsCurve1.add(trackingPoints.get(i));
					showTrackMapOverlaycurve1.addOverlayItem(overlayItem);
					break;
				case(2):
					trackingPointsCurve2.add(trackingPoints.get(i));
					showTrackMapOverlaycurve2.addOverlayItem(overlayItem);
					break;
				case(3):
					trackingPointsCurve3.add(trackingPoints.get(i));
					showTrackMapOverlaycurve3.addOverlayItem(overlayItem);
					break;
				case(4):
					trackingPointsCurve4.add(trackingPoints.get(i));
					showTrackMapOverlaycurve4.addOverlayItem(overlayItem);
					break;
				case(5):
					trackingPointsCurve5.add(trackingPoints.get(i));
					showTrackMapOverlaycurve5.addOverlayItem(overlayItem);
					break;
				case(6):
					trackingPointsCurve6.add(trackingPoints.get(i));
					showTrackMapOverlaycurve6.addOverlayItem(overlayItem);
					break;
				}
			}
			else if(trackingPoints.get(i).getNotes().length()>0){
				trackingPointsInfo.add(trackingPoints.get(i));
				showTrackMapOverlayInfo.addOverlayItem(overlayItem);
			}
			else{
				trackingPointsNone.add(trackingPoints.get(i));
				showTrackMapOverlay.addOverlayItem(overlayItem);
			}
			
			if(firstCall){
				mapView.getController().animateTo(geoPoint);
				firstCall=false;
			}
		}
	}
	// Clears all ArrayLists<TrackingPoint>
	private void clearAllLists(){
		trackingPoints.clear();
		trackingPointsCurve0.clear();
		trackingPointsCurve1.clear();
		trackingPointsCurve2.clear();
		trackingPointsCurve3.clear();
		trackingPointsCurve4.clear();
		trackingPointsCurve5.clear();
		trackingPointsCurve6.clear();
		trackingPointsInfo.clear();
		trackingPointsNone.clear();
	}
	
	//Clears all Overlay Items Arrays
	private void clearAllOverlays(){
		showTrackMapOverlay.clearOverlay();
		showTrackMapOverlayInfo.clearOverlay();
		showTrackMapOverlaycurve0.clearOverlay();
		showTrackMapOverlaycurve1.clearOverlay();
		showTrackMapOverlaycurve2.clearOverlay();
		showTrackMapOverlaycurve3.clearOverlay();
		showTrackMapOverlaycurve4.clearOverlay();
		showTrackMapOverlaycurve5.clearOverlay();
		showTrackMapOverlaycurve6.clearOverlay();
	}
	

	@Override
	protected void onStart() {
		// TODO Auto-generated method stub
		RallyeMaster.logDebug("OnStart");
	
		clearAllLists();
		clearAllOverlays();
		trackingPoints = dbTrackingPoint.getTrackingPointsFromTrack(selectedTrackID);
		fillShowTrackMapOverlay(trackingPoints);
		mapView.invalidate();
		super.onStart();
	}


	@Override
	protected boolean isRouteDisplayed() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
    public void onWindowFocusChanged(boolean b) {

         createOverlayWithListener();

    }
	
	// adding an listener to the overlay to simulate a long press for adding a new tracking point
	private void createOverlayWithListener() {
        //This time we use our own marker
        final ManagedOverlay managedOverlay = overlayManager.createOverlay("listenerOverlay", getResources().getDrawable(R.drawable.marker_green));
        for (int i = 0; i < 40; i = i + 3) {
            managedOverlay.createItem(GeoHelper.geopoint[i], "Item" + i);
        }
        managedOverlay.setOnOverlayGestureListener(new ManagedOverlayGestureDetector.OnOverlayGestureListener() {

			public boolean onDoubleTap(MotionEvent arg0, ManagedOverlay arg1,
					GeoPoint arg2, ManagedOverlayItem arg3) {
				// TODO Auto-generated method stub
				return false;
			}

			public void onLongPress(MotionEvent arg0, ManagedOverlay arg1) {
				// TODO Auto-generated method stub
				
				
			}

			public void onLongPressFinished(MotionEvent e,
					ManagedOverlay managedOverlay, GeoPoint geoPoint, ManagedOverlayItem managedOverlayItem) {
				// TODO Auto-generated method stub
				RallyeMaster.logDebug("ON LONG PRESSED");
				RallyeMaster.logDebug("GEOPOINT: " + geoPoint.toString());
				addGeoPoint = geoPoint;
				openContextMenu(mapView);
				
			}

			public boolean onScrolled(MotionEvent arg0, MotionEvent arg1,
					float arg2, float arg3, ManagedOverlay arg4) {
				// TODO Auto-generated method stub
				return false;
			}

			public boolean onSingleTap(MotionEvent arg0, ManagedOverlay arg1,
					GeoPoint arg2, ManagedOverlayItem arg3) {
				// TODO Auto-generated method stub
				return false;
			}

			public boolean onZoom(ZoomEvent arg0, ManagedOverlay arg1) {
				// TODO Auto-generated method stub
				return false;
			}


           
        });
        overlayManager.populate();
    }

	@Override
	public boolean onContextItemSelected(MenuItem item) {
		// TODO Auto-generated method stub
		switch(item.getItemId()){
			case(CONTEXT_ADD):{
				//RallyeMaster.logDebug("Add Tracking Point");
				TrackingPoint trackingPoint = new TrackingPoint();
				trackingPoint.setLatitude(addGeoPoint.getLatitudeE6()/1E6);
				trackingPoint.setLongitude(addGeoPoint.getLongitudeE6()/1E6);
				trackingPoint.setTrackId(selectedTrackID);
				//RallyeMaster.logDebug("Tracking Point : " +  trackingPoint.toString());
				dbTrackingPoint.insertTrackingPoint(trackingPoint);
				closeContextMenu();
				clearAllLists();
				clearAllOverlays();
				trackingPoints = dbTrackingPoint.getTrackingPointsFromTrack(selectedTrackID);
				fillShowTrackMapOverlay(trackingPoints);
				mapView.invalidate();
				mapView.getController().animateTo(addGeoPoint);
				Toast.makeText(mapView.getContext(), R.string.notification_insert, Toast.LENGTH_SHORT).show();
				
			}
		}
		return super.onContextItemSelected(item);
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		// TODO Auto-generated method stub
		menu.setHeaderTitle(currentTrack.getName());
		menu.add(0,CONTEXT_ADD,0,R.string.context_menu_add);
		super.onCreateContextMenu(menu, v, menuInfo);
		

	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// TODO Auto-generated method stub
		MenuItem newItem = menu.add(0,NEW_TRACK, Menu.NONE, R.string.itemMenu_new);
		MenuItem newItem1 = menu.add(0,OPTIONS_ITEM, Menu.NONE, R.string.itemMenu_options);
		newItem.setIcon(android.R.drawable.ic_menu_add);
		newItem1.setIcon(android.R.drawable.ic_menu_preferences);
		return super.onCreateOptionsMenu(menu);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// TODO Auto-generated method stub
		super.onOptionsItemSelected(item);
		switch(item.getItemId()){
			case NEW_TRACK:{
				Intent intent = new Intent(this, ListTrackActivity.class);
				startActivity(intent);
				return true;
			}
			case OPTIONS_ITEM:{
				Intent intent = new Intent(this, PreferencesActivity.class);
				startActivity(intent);
				return true;
			}
		}
		return false;
	}
	
	


}
